
local assert     = assert
local require    = require
local bit        = bit
local coroutine  = coroutine
local debug      = debug
local io         = io
local pairs      = pairs
local ipairs     = ipairs
local math       = math
local os         = os
local print      = print
local pcall      = pcall
local xpcall     = xpcall
local rawget     = rawget
local rawset     = rawset
local select     = select
local string     = string
local table      = table
local tonumber   = tonumber
local tostring	 = tostring
local error      = error
local type       = type
local unpack     = unpack
local setmetatable = setmetatable
local getmetatable = getmetatable
local ngx = ngx

local string_char  = string.char
local string_sub   = string.sub
local string_byte  = string.byte
local string_gsub  = string.gsub
local string_find  = string.find
local string_upper = string.upper

local math_fmod   = math.fmod
local math_floor  = math.floor
local math_pow    = math.pow
local math_abs    = math.abs

local table_insert = table.insert
local table_sort = table.sort

local os_date = os.date;
local table_concat = table.concat;


local uu         = require("modules.commhm.utils");
local log        = require("modules.commhm.log");
local ns_time    = require("modules.commhm.time");
local ns_network = require("modules.commhm.network");
local ns_utf8    = require("modules.commhm.utf8");

local ns_auth_comm_checker = require("modules.commhm.auth_comm_checker")

local CHtmlTable = require( "modules.html_page.CHtmlTable" )


local table_tostring = table.tostring
local table_loadstring = table.loadstring



local FOO = {
	_VERSION = '0.12.1',

	show_txt = {},

	now_ = 0,
};


FOO.header = [[<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ma_gate_list</title>
<script src="https://indevelop.mini1.cn:8088/oa/js_lib/angular.min.js"></script>
<script src="https://indevelop.mini1.cn:8088/oa/js_lib/cookie.min.js"></script>
<script src="https://indevelop.mini1.cn:8088/oa/js_lib/md5.js"></script>
<script src="https://indevelop.mini1.cn:8088/oa/js_lib/jquery-3.1.1.min.js"></script>
<script src="https://indevelop.mini1.cn:8088/oa/js_lib/miniajax.js"></script>
<style type="text/css">
	body,td,th { font-size: 15px; }
</style>
</head>
<body>]];


FOO.tail = [[
</body>
</html>
]];



function FOO.getDescByIP( ip_ )
	-- 共享内存上报的name
	local name_ = uu.get_server_cache_table( 1, 'ipn_' .. ip_ )
	if  type(name_) == 'table' and name_.v then
		return name_.v
	end

	return ""
end


local function sort_by_call_( a, b )
	return a.call > b.call
	--[[
	if  a.uri == b.uri then
		return a.call > b.call
	else
		return a.uri > b.uri
	end
	--]]
end


local function sort_by_cost_( a, b )

	return a.cost > b.cost
	--[[
	if  a.uri == b.uri then
		return a.cost > b.cost
	else
		return a.uri > b.uri
	end
	--]]
end


FOO.show = function( p_ma_gate_, p_target_, p_all_call_, ctrl_ )

	local show_call_mini_ = 1
	if  ctrl_.env == '0' then
		show_call_mini_ = 300
	end


	local max_rows_ = 30  ---最大展示数


	---合并排序表格   uri, code_
	-- 1
	local all_call_ = {}
	for uri_, info_ in pairs( p_all_call_ ) do
		for code_, v in pairs(info_) do
			if  v.call >= show_call_mini_ then
				all_call_[#all_call_ + 1] = { uri=uri_, code=code_, call=v.call, cost=v.cost }
			end
		end
	end
	table_sort( all_call_, sort_by_call_ )
	uu.var_dump( all_call_ )


	-- 2
	local ma_gate_ip_tmp_ = {}
	local ma_gate_ = {}   --ip_, uri, code_
	for ip_, ip_info_ in pairs( p_ma_gate_ ) do
		if  not ma_gate_ip_tmp_[ip_] then ma_gate_ip_tmp_[ip_] = { call=0, cost=0 } end
		for uri_, url_info_ in pairs( ip_info_ ) do
			for code_, v in pairs( url_info_ ) do
				ma_gate_ip_tmp_[ ip_ ].call = ma_gate_ip_tmp_[ ip_ ].call + v.call
				ma_gate_ip_tmp_[ ip_ ].cost = ma_gate_ip_tmp_[ ip_ ].cost + v.cost
				if  v.call >= show_call_mini_ then
					ma_gate_[ #ma_gate_ + 1 ] = { uri=uri_, ip=ip_, code=code_, call=v.call, cost=v.cost }
				end
			end
		end
	end
	table_sort( ma_gate_,    sort_by_call_ )
	uu.var_dump( ma_gate_ )


	-- 3
	local ma_gate_ip_ = { call=0, cost=0 }
	for ip_, v in pairs( ma_gate_ip_tmp_ ) do
		ma_gate_ip_[ #ma_gate_ip_ + 1 ] = { ip=ip_, call=v.call, cost=v.cost }
		ma_gate_ip_.call = ma_gate_ip_.call + v.call
		ma_gate_ip_.cost = ma_gate_ip_.cost + v.cost
	end
	table_sort( ma_gate_ip_, sort_by_call_ )


	-- 4
	local target_ip_tmp_ = {}
	local code_call_tmp_ = {}
	local path_call_tmp_ = {}
	local target_ = {}   --ip_, uri, code_
	for ip_, ip_info_ in pairs( p_target_ ) do
		if  not target_ip_tmp_[ip_] then target_ip_tmp_[ip_] = { call=0, cost=0 } end

		for uri_, url_info_ in pairs( ip_info_ ) do
			if  not path_call_tmp_[uri_] then path_call_tmp_[uri_] = { call=0, cost=0 } end

			for code_, v in pairs( url_info_ ) do
				target_ip_tmp_[ ip_ ].call = target_ip_tmp_[ ip_ ].call + v.call
				target_ip_tmp_[ ip_ ].cost = target_ip_tmp_[ ip_ ].cost + v.cost

				path_call_tmp_[ uri_ ].call = path_call_tmp_[ uri_ ].call + v.call
				path_call_tmp_[ uri_ ].cost = path_call_tmp_[ uri_ ].cost + v.cost

				if  not code_call_tmp_[code_] then code_call_tmp_[code_] = { call=0, cost=0 } end
				code_call_tmp_[code_].call = code_call_tmp_[code_].call + v.call
				code_call_tmp_[code_].cost = code_call_tmp_[code_].cost + v.cost

				if  v.call >= show_call_mini_ then
					target_[ #target_ + 1 ] = { uri=uri_, ip=ip_, code=code_, call=v.call, cost=v.cost }
				end
			end
		end
	end
	table_sort( target_,    sort_by_call_ )
	uu.var_dump( target_ )


	-- 5
	local target_ip_ = { call=0, cost=0 }
	for ip_, v in pairs( target_ip_tmp_ ) do
		target_ip_[ #target_ip_ + 1 ] = { ip=ip_, call=v.call, cost=v.cost }
		target_ip_.call = target_ip_.call + v.call
		target_ip_.cost = target_ip_.cost + v.cost
	end
	table_sort( target_ip_, sort_by_call_ )


	-- 6
	local code_call_ = {}
	for code_, v in pairs( code_call_tmp_ ) do
		code_call_[ #code_call_ + 1 ] = { code=code_, call=v.call, cost=v.cost }
	end
	table_sort( code_call_, sort_by_call_ )


	-- 7
	local path_call_ = { call=0, cost=0 }
	for path_, v in pairs( path_call_tmp_ ) do
		path_call_[ #path_call_ + 1 ] = { path=path_, call=v.call, cost=v.cost }
		path_call_.call = path_call_.call + v.call
		path_call_.cost = path_call_.cost + v.cost
	end
	table_sort( path_call_, sort_by_call_ )


	FOO.clean_txt()
	FOO.add_txt( FOO.header )
	FOO.now = uu.now()


	--- ===============================开始打印================

	-- 所有网关总调用量排序 按IP区分
	--{{{
	FOO.add_txt( '<h3 style="font-size: 20px;" > 所有网关总综合每秒统计: '
			.. math_floor(ma_gate_ip_.cost / 30) .. '(耗时) / ' .. math_floor(ma_gate_ip_.call / 30) .. '(tps) = '
			.. math_floor(ma_gate_ip_.cost / ma_gate_ip_.call) .. '</h3><br>' )

	FOO.add_txt( '<table border=3 cellpadding=10>\n' )   --1 all
	FOO.add_txt( '<tr><td align="center">单个网关每秒: 调用次数排序</td><td align="center">耗时排序</td></tr>' )
	FOO.add_txt( '<tr><td valign="top">\n' )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>ip</td><td>desc</td><td>调用次数</td><td>总耗时</td><td>平均耗时</td></tr>' )
	for i=1, #ma_gate_ip_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. ma_gate_ip_[i].ip .. '</td>' )
		FOO.add_txt( '<td>' .. FOO.getDescByIP(ma_gate_ip_[i].ip) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_ip_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_ip_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_ip_[i].cost / ma_gate_ip_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>\n' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td><td>' )

	table_sort( ma_gate_ip_, sort_by_cost_ )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>ip</td><td>desc</td><td>总耗时</td><td>调用次数</td><td>平均耗时</td></tr>' )
	for i=1, #ma_gate_ip_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. ma_gate_ip_[i].ip .. '</td>' )
		FOO.add_txt( '<td>' .. FOO.getDescByIP(ma_gate_ip_[i].ip) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_ip_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_ip_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_ip_[i].cost / ma_gate_ip_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td></tr>' )
	FOO.add_txt( '</table>\n' )   --1 all
	--}}}


	-- 各业务调用量排序 按IP区分
	--{{{
	FOO.add_txt( '<h3 style="font-size: 20px;" > 各业务服务器（被调用方）调用量排序 按IP区分 '
			.. math_floor(target_ip_.cost / 30) .. '(耗时) / ' .. math_floor(target_ip_.call / 30) .. '(tps) = '
			.. math_floor(target_ip_.cost / target_ip_.call) .. '</h3>' )

	FOO.add_txt( '<table border=3 cellpadding=10>\n' )   --1 all
	FOO.add_txt( '<tr><td align="center">每秒 调用次数排序</td><td align="center">总耗时排序</td></tr>' )
	FOO.add_txt( '<tr><td valign="top">\n' )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>ip</td><td>desc</td><td>调用次数</td><td>总耗时</td><td>平均耗时</td></tr>' )
	for i=1, #target_ip_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. target_ip_[i].ip .. '</td>' )
		FOO.add_txt( '<td>' .. FOO.getDescByIP(target_ip_[i].ip) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_ip_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_ip_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_ip_[i].cost / target_ip_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>\n' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td><td>' )

	table_sort( target_ip_, sort_by_cost_ )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>ip</td><td>desc</td><td>总耗时</td><td>调用次数</td><td>平均耗时</td></tr>' )
	for i=1, #target_ip_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. target_ip_[i].ip .. '</td>' )
		FOO.add_txt( '<td>' .. FOO.getDescByIP(target_ip_[i].ip) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_ip_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_ip_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_ip_[i].cost / target_ip_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td></tr>' )
	FOO.add_txt( '</table>\n' )   --1 all
	--}}}



	-- 各业务调用量排序 按path区分
	--{{{
	FOO.add_txt( '<h3 style="font-size: 20px;" > 各业务调用量排序 按path区分 '
			.. math_floor(path_call_.cost/30) .. '(耗时) / ' .. math_floor(path_call_.call/30) .. '(tps) = '
			.. math_floor( path_call_.cost / path_call_.call ) .. '</h3>' )

	FOO.add_txt( '<table border=3 cellpadding=10>\n' )   --1 all
	FOO.add_txt( '<tr><td align="center">每秒 调用次数排序</td><td align="center">每秒 耗时排序</td></tr>' )
	FOO.add_txt( '<tr><td valign="top">\n' )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>path</td><td>调用次数</td><td>总耗时</td><td>平均耗时</td></tr>' )
	for i=1, #path_call_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. path_call_[i].path .. '</td>' )
		--FOO.add_txt( '<td>' .. path_call_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( path_call_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( path_call_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( path_call_[i].cost / path_call_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>\n' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td><td>' )

	table_sort( path_call_, sort_by_cost_ )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>ip</td><td>总耗时</td><td>调用次数</td><td>平均耗时</td></tr>' )
	for i=1, #path_call_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. path_call_[i].path .. '</td>' )
		--FOO.add_txt( '<td>' .. path_call_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( path_call_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( path_call_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( path_call_[i].cost / path_call_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td></tr>' )
	FOO.add_txt( '</table>\n' )   --1 all
	--}}}


	-- 各业务调用量排序 按function区分
	--{{{
	FOO.add_txt( '<h3 style="font-size: 20px;" > 各业务调用量排序 按function区分 </h3>\n' )

	FOO.add_txt( '<table border=3 cellpadding=10>\n' )   --1 all
	FOO.add_txt( '<tr><td align="center">按每秒调用次数排序</td><td align="center">按每秒总耗时排序</td></tr>' )
	FOO.add_txt( '<tr><td valign="top">\n' )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>function</td><td>调用次数</td><td>总耗时</td><td>平均耗时</td></tr>' )
	for i=1, #code_call_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. code_call_[i].code .. '</td>' )
		--FOO.add_txt( '<td>' .. code_call_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( code_call_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( code_call_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( code_call_[i].cost / code_call_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>\n' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td><td>' )

	table_sort( code_call_, sort_by_cost_ )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>ip</td><td>总耗时</td><td>调用次数</td><td>平均耗时</td></tr>' )
	for i=1, #code_call_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. code_call_[i].code .. '</td>' )
		--FOO.add_txt( '<td>' .. code_call_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( code_call_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( code_call_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( code_call_[i].cost / code_call_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td></tr>' )
	FOO.add_txt( '</table>\n' )   --1 all
	--}}}



	-- ma_gate 全网调用,按path+function分
	--{{{
	FOO.add_txt( '<h3 style="font-size: 20px;" >ma_gate 全网调用 按path+function分</h3>\n' )

	FOO.add_txt( '<table border=3 cellpadding=10>\n' )   --1 all
	FOO.add_txt( '<tr><td align="center">全网按每秒调用次数排序</td><td align="center">全网按每秒总耗时排序</td></tr>' )
	FOO.add_txt( '<tr><td valign="top">\n' )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>path</td><td>function</td><td>调用次数</td><td>总耗时</td><td>平均耗时</td></tr>' )
	for i=1, #all_call_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. all_call_[i].uri .. '</td>' )
		FOO.add_txt( '<td>' .. all_call_[i].code .. '</td>' )
		--FOO.add_txt( '<td>' .. all_call_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( all_call_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( all_call_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( all_call_[i].cost / all_call_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>\n' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td><td>' )

	table_sort( all_call_, sort_by_cost_ )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>path</td><td>function</td><td>总耗时</td><td>调用次数</td><td>平均耗时</td></tr>' )
	for i=1, #all_call_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. all_call_[i].uri .. '</td>' )
		FOO.add_txt( '<td>' .. all_call_[i].code .. '</td>' )
		--FOO.add_txt( '<td>' .. all_call_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( all_call_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( all_call_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( all_call_[i].cost / all_call_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td></tr>' )
	FOO.add_txt( '</table>\n' )   --1 all
	--}}}


	-- ma_gate 全网调用,按IP+path+function分
	--{{{
	FOO.add_txt( '<h3 style="font-size: 20px;" >ma_gate 按IP+path+function区分</h3>\n' )

	FOO.add_txt( '<table border=3 cellpadding=10>\n' )   --1 all
	FOO.add_txt( '<tr><td align="center">按每秒调用次数排序</td><td align="center">按每秒总耗时排序</td></tr>' )
	FOO.add_txt( '<tr><td valign="top">\n' )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>IP</td><td>path</td><td>function</td><td>调用次数</td><td>总耗时</td><td>平均耗时</td></tr>' )
	for i=1, #ma_gate_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. ma_gate_[i].ip .. '</td>' )
		FOO.add_txt( '<td>' .. ma_gate_[i].uri .. '</td>' )
		FOO.add_txt( '<td>' .. ma_gate_[i].code .. '</td>' )
		--FOO.add_txt( '<td>' .. ma_gate_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_[i].cost / ma_gate_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>\n' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td><td>' )

	table_sort( ma_gate_, sort_by_cost_ )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>IP</td><td>path</td><td>function</td><td>总耗时</td><td>调用次数</td><td>平均耗时</td></tr>' )
	for i=1, #ma_gate_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. ma_gate_[i].ip .. '</td>' )
		FOO.add_txt( '<td>' .. ma_gate_[i].uri .. '</td>' )
		FOO.add_txt( '<td>' .. ma_gate_[i].code .. '</td>' )
		--FOO.add_txt( '<td>' .. ma_gate_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( ma_gate_[i].cost / ma_gate_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td></tr>' )
	FOO.add_txt( '</table>\n' )   --1 all
	--}}}


	-- 全网调用,按被调用者IP+path+function分
	--{{{
	FOO.add_txt( '<h3 style="font-size: 20px;" >被调用方 分IP+path+function调用</h3>\n' )

	FOO.add_txt( '<table border=3 cellpadding=10>\n' )   --1 all
	FOO.add_txt( '<tr><td align="center">按每秒调用次数排序</td><td align="center">按每秒总耗时排序</td></tr>' )
	FOO.add_txt( '<tr><td valign="top">\n' )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>IP</td><td>path</td><td>function</td><td>调用次数</td><td>总耗时</td><td>平均耗时</td></tr>' )
	for i=1, #target_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. target_[i].ip .. '</td>' )
		FOO.add_txt( '<td>' .. target_[i].uri .. '</td>' )
		FOO.add_txt( '<td>' .. target_[i].code .. '</td>' )
		--FOO.add_txt( '<td>' .. target_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_[i].cost / target_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>\n' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td><td>' )

	table_sort( target_, sort_by_cost_ )

	FOO.add_txt( '<table border=2 cellpadding=2>\n' )   --2
	FOO.add_txt( '<tr><td>seq</td><td>IP</td><td>path</td><td>function</td><td>总耗时</td><td>调用次数</td><td>平均耗时</td></tr>' )
	for i=1, #target_ do
		FOO.add_txt( '<tr>' )
		FOO.add_txt( '<td>' .. i .. '</td>' )
		FOO.add_txt( '<td>' .. target_[i].ip .. '</td>' )
		FOO.add_txt( '<td>' .. target_[i].uri .. '</td>' )
		FOO.add_txt( '<td>' .. target_[i].code .. '</td>' )
		--FOO.add_txt( '<td>' .. target_[i].call .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_[i].cost / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_[i].call / 30 ) .. '</td>' )
		FOO.add_txt( '<td align="right">' .. math.floor( target_[i].cost / target_[i].call ).. '</td>' )
		FOO.add_txt( '</tr>' )
		if  i>=max_rows_ then
			break;
		end
	end
	FOO.add_txt( '</table>\n' )   --2

	FOO.add_txt( '</td></tr>' )
	FOO.add_txt( '</table>\n' )   --1 all
	--}}}


	FOO.add_txt( FOO.tail )
	ngx.say( FOO.get_txt() )

end


-----------------------------------------------------------
---清理输出
FOO.clean_txt = function()
	FOO.show_txt = {};
end

---增加输出内容
FOO.add_txt = function( txt_ )
	FOO.show_txt[ #FOO.show_txt + 1 ] = txt_
end


---获得所有输出
FOO.get_txt = function()
	return table_concat( FOO.show_txt )
end


return FOO;